// Carte des concepts : nœuds (avec maîtrise) + liens typés + compteurs de ressources. import { NextResponse } from "next/server"; import { apiError, requireEnrollment } from "@/lib/api.ts"; import { requireUser } from "@/lib/auth/session.ts"; import { all } from "@/lib/db/index.ts"; import { masteryForCourse } from "@/lib/learning/mastery.ts"; import { normalizeCourse } from "@/lib/learning/helpers.ts"; export async function GET(_req: Request, ctx: { params: Promise<{ course: string }> }) { try { const user = await requireUser(); const course = normalizeCourse((await ctx.params).course); requireEnrollment(user.id, course); const mastery = new Map(masteryForCourse(user.id, course).map((m) => [m.conceptId, m])); const concepts = all<{ id: number; slug: string; name: string; description: string; week: number | null; importance: number; axis: string }>( "SELECT id, slug, name, description, week, importance, axis FROM concepts WHERE course_code = ? ORDER BY week, id", course ); const counts = new Map(); for (const r of all<{ concept_id: number; n: number }>( "SELECT concept_id, COUNT(*) as n FROM flashcards WHERE course_code = ? AND concept_id IS NOT NULL GROUP BY concept_id", course )) counts.set(r.concept_id, { cards: r.n, questions: 0 }); for (const r of all<{ concept_id: number; n: number }>( "SELECT concept_id, COUNT(*) as n FROM quiz_questions WHERE course_code = ? AND concept_id IS NOT NULL GROUP BY concept_id", course )) { const e = counts.get(r.concept_id) ?? { cards: 0, questions: 0 }; e.questions = r.n; counts.set(r.concept_id, e); } const ids = concepts.map((c) => c.id); const links = ids.length ? all<{ from_id: number; to_id: number; type: string }>( `SELECT from_id, to_id, type FROM concept_links WHERE from_id IN (${ids.map(() => "?").join(",")}) OR to_id IN (${ids.map(() => "?").join(",")})`, ...ids, ...ids ) : []; return NextResponse.json({ nodes: concepts.map((c) => ({ ...c, mastery: mastery.get(c.id)?.score ?? 0, level: mastery.get(c.id)?.level ?? "a-decouvrir", observations: mastery.get(c.id)?.observations ?? 0, cards: counts.get(c.id)?.cards ?? 0, questions: counts.get(c.id)?.questions ?? 0, })), links, }); } catch (e) { return apiError(e); } }